bitkeeper revision 1.22.2.14 (3e4a8602WvipwBgbN9VwA2dW6eIyhA)
authorkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 12 Feb 2003 17:36:02 +0000 (17:36 +0000)
committerkaf24@labyrinth.cl.cam.ac.uk <kaf24@labyrinth.cl.cam.ac.uk>
Wed, 12 Feb 2003 17:36:02 +0000 (17:36 +0000)
processor.h, traps.c, smpboot.c, process.c:
  Another fix to fast-trap handling. :-) We needed per-CPU IDTs...

xen-2.4.16/arch/i386/process.c
xen-2.4.16/arch/i386/smpboot.c
xen-2.4.16/arch/i386/traps.c
xen-2.4.16/include/asm-i386/processor.h

index a23f4b1557453323908b2d7571cbeb7c12a0d8ce..d3cedf47666509da191ed7394448575d75d6bdfe 100644 (file)
@@ -364,7 +364,6 @@ void new_thread(struct task_struct *p,
 /* NB. prev_p passed in %eax, next_p passed in %edx */
 void __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
 {
-    extern struct desc_struct idt_table[];
     struct thread_struct *prev = &prev_p->thread,
         *next = &next_p->thread;
     struct tss_struct *tss = init_tss + smp_processor_id();
index dd0f94bd137b0082ea7a9eac1f0caf52df1dc1fd..f7a5f8f56acb293d2c674579f6c67acb23e3e268 100644 (file)
@@ -395,6 +395,10 @@ int cpucount;
  */
 int __init start_secondary(void *unused)
 {
+    unsigned int cpu = smp_processor_id();
+    /* A 'mem64' suitable for passing to LIDT instruction. */
+    unsigned long idt_load[2] = { (IDT_ENTRIES*8)-1, 0 };
+
     extern void cpu_init(void);
 
     /*
@@ -408,6 +412,15 @@ int __init start_secondary(void *unused)
     while (!atomic_read(&smp_commenced))
         rep_nop();
 
+    /*
+     * At this point, boot CPU has fully initialised the IDT. It is
+     * now safe to make ourselves a private copy.
+     */
+    idt_tables[cpu] = kmalloc(IDT_ENTRIES*8, GFP_KERNEL);
+    memcpy(idt_tables[cpu], idt_table, IDT_ENTRIES*8);
+    idt_load[2] = (unsigned long)idt_tables[cpu];
+    __asm__ __volatile__ ( "lidt %0" : "=m" (idt_load) );
+
     /*
      * low-memory mappings have been cleared, flush them from the local TLBs 
      * too.
index cdea19eaa63e19c3a9350753dcd66db458ca6879..b8297fe3eb6c40bd36f6210eeb70e64480fb18ef 100644 (file)
@@ -43,12 +43,10 @@ asmlinkage int hypervisor_call(void);
 asmlinkage void lcall7(void);
 asmlinkage void lcall27(void);
 
-/*
- * The IDT has to be page-aligned to simplify the Pentium
- * F0 0F bug workaround.. We have a special link segment
- * for this.
- */
-struct desc_struct idt_table[256] __attribute__((__section__(".data.idt"))) = { {0, 0}, };
+/* Master table, and the one used by CPU0. */
+struct desc_struct idt_table[256] = { {0, 0}, };
+/* All other CPUs have their own copy. */
+struct desc_struct *idt_tables[NR_CPUS] = { 0 };
 
 asmlinkage void divide_error(void);
 asmlinkage void debug(void);
@@ -299,7 +297,12 @@ asmlinkage void do_general_protection(struct pt_regs * regs, long error_code)
         ti = current->thread.traps + (error_code>>3);
         if ( ti->dpl >= (regs->xcs & 3) )
         {
-            if ( (error_code>>3)==0x80 ) { printk("!!!\n"); BUG(); }
+            /* XXX Kill next conditional soon :-) XXX */
+            if ( (error_code>>3)==0x80 ) 
+            { 
+                printk("DIDN'T USE FAST-TRAP HANDLER FOR 0x80!!! :-(\n");
+                BUG(); 
+            }
             gtb->flags = GTBF_TRAP_NOCODE;
             gtb->cs    = ti->cs;
             gtb->eip   = ti->address;
@@ -542,6 +545,9 @@ void __init trap_init(void)
     /* Only ring 1 can access monitor services. */
     _set_gate(idt_table+HYPERVISOR_CALL_VECTOR,15,1,&hypervisor_call);
 
+    /* CPU0 uses the master IDT. */
+    idt_tables[0] = idt_table;
+
     /*
      * Should be a barrier for any external CPU state.
      */
index f7f949d82b6395236c4d1be06dda62091f4d77a5..36a50b29763bf3645f5ce34c4ac8938eb6772db9 100644 (file)
@@ -358,16 +358,22 @@ struct thread_struct {
     trap_info_t         traps[256];
 };
 
+#define IDT_ENTRIES 256
+extern struct desc_struct idt_table[];
+extern struct desc_struct *idt_tables[];
+
 #define SET_DEFAULT_FAST_TRAP(_p) \
     (_p)->fast_trap_idx = 0x20;   \
     (_p)->fast_trap_desc.a = 0;   \
     (_p)->fast_trap_desc.b = 0;
 
 #define CLEAR_FAST_TRAP(_p) \
-    (memset(idt_table + (_p)->fast_trap_idx, 0, 8))
+    (memset(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+     0, 8))
 
 #define SET_FAST_TRAP(_p)   \
-    (memcpy(idt_table + (_p)->fast_trap_idx, &((_p)->fast_trap_desc), 8))
+    (memcpy(idt_tables[smp_processor_id()] + (_p)->fast_trap_idx, \
+     &((_p)->fast_trap_desc), 8))
 
 #define INIT_THREAD  {                                         \
        sizeof(idle0_stack) + (long) &idle0_stack, /* esp0 */   \